﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using BLL.DataContextClasses;

namespace BLL.BusinessClasses
{
    public class Vacante
    {
        // Campos
        private int id;
        private bool siActiva;
        private string descripcion;
        private string puesto;
        private Empresa publicante;
        private DateTime fechaPublicacion;
        private Nullable<DateTime> fechaCierre;
        private List<Aplicacion> aplicaciones;
        private Carrera carrera;
        private List<Habilidad> habilidades;
        private List<Postgrado> estudiosRequeridos;
        private Pais pais;

        // Propiedades
        public int ID
        {
            get { return this.id; }
            set { this.id = value; }
        }
        public bool SiActiva
        {
            get { return this.siActiva; }
            set { this.siActiva = value; }
        }
        public string Descripcion
        {
            get { return this.descripcion; }
            set { this.descripcion = value.Trim(); }
        }
        public string Puesto
        {
            get { return this.puesto; }
            set { this.puesto = value.Trim(); }
        }
        public Empresa Publicante
        {
            get
            {
                if (this.publicante == null)
                {
                    this.publicante = Empresa.GetPublicanteByVacanteID(this.ID);
                }
                return this.publicante;
            }
            set { this.publicante = value; }
        }
        public DateTime FechaPublicacion
        {
            get { return this.fechaPublicacion; }
        }
        public Nullable<DateTime> FechaCierre
        {
            get { return this.fechaCierre; }
            set { this.fechaCierre = value; }
        }
        public List<Aplicacion> Aplicaciones
        {
            get
            {
                if (this.aplicaciones == null)
                {
                    this.aplicaciones = Aplicacion.GetAplicacionesByVacanteID(this.ID);
                }
                return this.aplicaciones;
            }
            set { this.aplicaciones = value; }
        }
        public Carrera Carrera
        {
            get
            {
                if (this.carrera == null) this.carrera = Carrera.GetCarreraByVacanteID(this.ID);
                return this.carrera;
            }
            set { this.carrera = value; }
        }
        public List<Habilidad> Habilidades
        {
            get
            {
                if (this.habilidades == null)
                {
                    this.habilidades = Habilidad.GetHabilidadesByVacante(this.ID);
                }
                return this.habilidades;
            }
            set { this.habilidades = value; }
        }

        public List<Postgrado> EstudiosRequeridos
        {
            get
            {
                if (this.estudiosRequeridos == null) this.estudiosRequeridos = Postgrado.GetPostgradosByVacanteID(this.ID);
                return this.estudiosRequeridos;
            }

            set { this.estudiosRequeridos = value; }
        }

        public Pais Pais
        {
            get
            {
                if (this.pais == null) this.pais = Pais.GetPaisByVacanteID(this.ID);
                return this.pais;
            }

            set { this.pais = value; }
        }
        //Constructores
        public Vacante(int IDToSearch)
        {
            DataClassesDataContext DB = new DataClassesDataContext();

            try
            {
                DataContextClasses.Vacante Vac = (from v in DB.Vacantes
                                                  where v.ID == IDToSearch
                                                  select v).First();

                this.id = Vac.ID;
                this.siActiva = Vac.Activa;
                this.descripcion = Vac.Descripcion;
                this.fechaPublicacion = Vac.FechaPublicacion;
                this.fechaCierre = Vac.FechaCierre;
                this.puesto = Vac.Puesto;
                this.publicante = null; //new Empresa(Vac.Empresa.ID);
                this.carrera = null;
                this.aplicaciones = null;
            }
            catch (SqlException SqlEx)
            {
                throw new Exception("No existe tal vacante\n" + SqlEx.Message);
            }
        }
        public Vacante(int EmpresaID, string Descripcion, int CarreraID)
        {
            //this.id = Vac.ID;
            this.siActiva = true;
            this.descripcion = Descripcion;
            this.fechaPublicacion = DateTime.Now;
            this.fechaCierre = null;
            this.publicante = new Empresa(EmpresaID);
            this.carrera = new Carrera(CarreraID);
            this.aplicaciones = null;
            this.puesto = null;
        }
        public Vacante()
        {
            this.siActiva = true;
            this.fechaPublicacion = DateTime.Now;
        }

        //Metodos
        public void Insertar()
        {
            DataClassesDataContext DB = new DataClassesDataContext();

            DataContextClasses.Vacante VacanteToInsert = new DataContextClasses.Vacante();
            try
            {
                VacanteToInsert.Activa = this.siActiva;
                VacanteToInsert.Descripcion = this.descripcion;
                VacanteToInsert.FechaPublicacion = this.fechaPublicacion;
                VacanteToInsert.FechaCierre = this.fechaCierre;
                VacanteToInsert.ID_Empresa = this.Publicante.ID;
                VacanteToInsert.ID_Carrera = this.carrera.ID;
                VacanteToInsert.ID_Pais = this.Pais.ID;
                VacanteToInsert.Puesto = this.puesto;

                DB.Vacantes.InsertOnSubmit(VacanteToInsert);

                DB.SubmitChanges();

                this.id = VacanteToInsert.ID;
            }
            catch (SqlException ex)
            {
                throw new Exception("Hubo un problema con la Base de datos\n" + ex.Message);
            }            

            // Asociando las habilidades
            try
            {
                foreach (Habilidad item in this.habilidades)
                {
                    DB.Vacantes_Habilidades.InsertOnSubmit(new Vacantes_Habilidade() { ID_Habilidad = item.ID, ID_Vacante = this.ID });
                }


                DB.SubmitChanges();
            }
            catch (SqlException ex)
            {
                throw new Exception("Hubo un problema con la Base de datos, no se pudieron agregar las habilidades\n" + ex.Message);
            }

            // Asociando los postgrados
            try
            {
                foreach (Postgrado item in this.estudiosRequeridos)
                {
                    DB.Vacantes_Postgrados.InsertOnSubmit(new Vacantes_Postgrado() { ID_Postgrado = item.ID, ID_Vacante = this.ID });
                }

                DB.SubmitChanges();
            }
            catch (SqlException ex)
            {
                throw new Exception("Hubo un problema con la Base de datos, no se pudieron agregar los postgrados\n" + ex.Message);
            }
        }
        public void Actualizar()
        {
            DataClassesDataContext DB = new DataClassesDataContext();
            try
            {
                DataContextClasses.Vacante VacanteToUpdate = (from v in DB.Vacantes
                                                      where v.ID == this.id
                                                      select v).First();

                VacanteToUpdate.ID = this.id;
                VacanteToUpdate.Activa = this.siActiva;
                VacanteToUpdate.Descripcion = this.descripcion;
                VacanteToUpdate.FechaPublicacion = this.fechaPublicacion;
                VacanteToUpdate.FechaCierre = this.fechaCierre;
                VacanteToUpdate.ID_Empresa = this.Publicante.ID;
                VacanteToUpdate.ID_Carrera = this.Carrera.ID;
                VacanteToUpdate.ID_Pais = this.Pais.ID;
                VacanteToUpdate.Puesto = this.puesto;

                DB.SubmitChanges();

            }
            catch (Exception ex)
            {
                throw new Exception("Hubo un problema con la Base de datos\n" + ex.Message);
            }
        }

        #region Metodo k no se usa
        /*
        public void AgregarAplicaciones()
        {
            bool YaEstaRelacionada;

            DataClassesDataContext DB = new DataClassesDataContext();

            //this.id no existe en este punto!
            var HabilidadesRelacionadas = (from v in DB.Vacantes_Habilidades
                                           where v.ID_Vacante == this.id
                                           select v);

            List<Habilidad> HabilidadesARelacionar = new List<Habilidad>();

            foreach (Habilidad Habilidad in this.Habilidades)
            {
                YaEstaRelacionada = false;
                foreach (var item in HabilidadesRelacionadas)
                {
                    if (Habilidad.ID == item.ID_Habilidad) YaEstaRelacionada = true;
                }
                if (YaEstaRelacionada == false) HabilidadesARelacionar.Add(Habilidad);
            }

            try
            {
                foreach (var item in HabilidadesARelacionar)
                {
                    DataContextClasses.Vacantes_Habilidade RelacionVacante_Habiliad = new DataContextClasses.Vacantes_Habilidade();

                    RelacionVacante_Habiliad.ID_Vacante = this.ID;
                    RelacionVacante_Habiliad.ID_Habilidad = item.ID;

                    DB.Vacantes_Habilidades.InsertOnSubmit(RelacionVacante_Habiliad);

                    DB.SubmitChanges();
                }
            }
            catch (Exception ex)
            {
#warning Recuerda cambiar este WriteLine por una exception
                Console.WriteLine("Hubo un problema con la Base de datos\n" + ex.Message);
                //throw new SystemExceptions.InvalidUserException("No existe tal usuario o su username o password estan mal escritos\n" + InvOperEx.Message);
            }
        }
        */
        #endregion

        public void ToggleActivation()
        {
            try
            {
                this.siActiva = !(this.siActiva);
                this.Actualizar();
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
        }
       
        public static List<Vacante> GetAllVacantes()
        {
            try
            {
                DataClassesDataContext DB = new DataClassesDataContext();
                List<Vacante> ListVacanteToReturn = new List<Vacante>();

                var QueryVacantes = from v in DB.Vacantes
                                    select v;

                foreach (DataContextClasses.Vacante item in QueryVacantes)
                {
                    ListVacanteToReturn.Add(new Vacante(item.ID));
                }

                return ListVacanteToReturn;
            }
            catch (Exception ex)
            {
                throw new Exception("Hubo un problema con la Base de datos\n" + ex.Message);
            }
        }

        public static Vacante GetVacanteByAplicacionID(int AplicacionID)
        {
            try
            {
                DataClassesDataContext DB = new DataClassesDataContext();

                DataContextClasses.Aplicacione Apl = (from a in DB.Aplicaciones
                                                      where a.ID == AplicacionID
                                                      select a).First();

                Vacante VacanteAplicada = new Vacante(Apl.ID_Vacante);
                return VacanteAplicada;
            }
            catch (Exception ex)
            {
                throw new Exception("Hubo un problema con la Base de datos\n" + ex.Message);
            }
        }

        public static DateTime GetNewFechaCierre()
        {
            DataClassesDataContext DB = new DataClassesDataContext();

            string TVV = (from con in DB.Configuraciones
                          where con.Nombre == "TiempoDeVidaVacante"
                          select con.Valor).First();

            double TiempoVidaVacante = System.Convert.ToInt32(TVV);

            DateTime NewFechaCierre = DateTime.Now.AddDays(TiempoVidaVacante);

            return NewFechaCierre;
        }

        public static List<Vacante> GetVacantesByEmpresaID(int EmpresaID)
        {
            try
            {
                DataClassesDataContext DB = new DataClassesDataContext();

                var VacantesEmpresa = (from v in DB.Vacantes
                                       where v.ID_Empresa == EmpresaID
                                       select v);

                List<Vacante> VacantesDeEmpresa = new List<Vacante>();

                foreach (var item in VacantesEmpresa)
                {
                    Vacante VacanteAIntroducir = new Vacante(item.ID);
                    VacantesDeEmpresa.Add(VacanteAIntroducir);
                }
                return VacantesDeEmpresa;
            }
            catch (Exception ex)
            {
                throw new Exception("Hubo un problema con la Base de datos\n" + ex.Message);
            }
        }
       
        //Funcion que encuentra los egresados que cumplen con la solicitud y saca sus mails.
        //Debido al cambio en egresados (que ahora pueden tener mas de una carrera) este metodo ya no funciona
#warning No Funciona!
        /*
        public void EncontrarSolicitantes()
        {
            int NoHab;

            DataClassesDataContext DB = new DataClassesDataContext();

            var Egresados = from e in DB.Egresados
                            where e.Carrera.Descripcion == this.Carrera.Descripcion
                            //where e.Egresados_Habilidades.ElementAt(1) == this.habilidades.e
                            select e;

            List<UsuarioEgresado> EgresadosAprobados = new List<UsuarioEgresado>();

            foreach (var item in Egresados)
            {
                UsuarioEgresado EgresadoAEvaluar = new UsuarioEgresado(item.ID);
                NoHab = 0;
                foreach (Habilidad EgrHab in EgresadoAEvaluar.Habilidades)
                {
                    foreach (var VacHab in this.Habilidades)
                    {
                        if (EgrHab.ID == VacHab.ID) NoHab++;
                    }
                }


                if (NoHab == this.habilidades.Count) EgresadosAprobados.Add(EgresadoAEvaluar);
            }


            //List<Contacto> Mails = new List<Contacto>();
            Envio Env = new Envio(Publicante,1);

            foreach (UsuarioEgresado item in EgresadosAprobados)
            {
                foreach (Contacto Mail in item.Contactos)
                {
                    if (Mail.TipoContacto.Trim() == "Email")
                        //Mails.Add(Mail);
                        Env.EnviarMailSolicitud(Mail);
                }
            }
        }
        */
    }
}

